#include "delge_squirrelgraphics_mesh.h"

void s_Graphics_Mesh_RegisterFunctions (HSQUIRRELVM v)
{
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_Create,					_SC("Mesh_Create"),						_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_Destroy,					_SC("Mesh_Destroy"),					_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_AddVertex,					_SC("Mesh_AddVertex"),					_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_AddTriangle,				_SC("Mesh_AddTriangle"),				_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_RemoveVertex,				_SC("Mesh_RemoveVertex"),				_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_RemoveTriangle,			_SC("Mesh_RemoveTriangle"),				_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_Clear,						_SC("Mesh_Clear"),						_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_Build,						_SC("Mesh_Build"),						_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_SetVertexPosition,			_SC("Mesh_SetVertexPosition"),			_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexPositionX,		_SC("Mesh_GetVertexPositionX"),			_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexPositionY,		_SC("Mesh_GetVertexPositionY"),			_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexPositionZ,		_SC("Mesh_GetVertexPositionZ"),			_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_SetVertexTexturePosition,	_SC("Mesh_SetVertexTexturePosition"),	_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexTexturePositionU,	_SC("Mesh_GetVertexTexturePositionU"),	_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexTexturePositionV,	_SC("Mesh_GetVertexTexturePositionV"),	_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_SetVertexColor,			_SC("Mesh_SetVertexColor"),				_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexColorRed,			_SC("Mesh_GetVertexColorRed"),			_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexColorGreen,		_SC("Mesh_GetVertexColorGreen"),		_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexColorBlue,		_SC("Mesh_GetVertexColorBlue"),			_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexColorAlpha,		_SC("Mesh_GetVertexColorAlpha"),		_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_SetVertexNormal,			_SC("Mesh_SetVertexNormal"),			_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexNormalX,			_SC("Mesh_GetVertexNormalX"),			_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexNormalY,			_SC("Mesh_GetVertexNormalY"),			_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexNormalZ,			_SC("Mesh_GetVertexNormalZ"),			_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetVertexCount,			_SC("Mesh_GetVertexCount"),				_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_GetTriangleCount,			_SC("Mesh_GetTriangleCount"),			_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_NeedsRebuilding,			_SC("Mesh_NeedsRebuilding"),			_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_Translate,					_SC("Mesh_Translate"),					_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_Scale,						_SC("Mesh_Scale"),						_SC("*"));
	SquirrelVM::CreateFunctionGlobal(s_Graphics_Mesh_Rotate,					_SC("Mesh_Rotate"),						_SC("*"));
}

SQInteger s_Graphics_Mesh_Create (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;

	sq_getstring			(v, 2, &sMeshName);

	Mesh *pMesh = new Mesh();

	ResourceManager<Mesh>::LoadResource(string(sMeshName), pMesh);

	return 0;
}

SQInteger s_Graphics_Mesh_Destroy (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;

	sq_getstring			(v, 2, &sMeshName);

	ResourceManager<Mesh>::UnloadResource(string(sMeshName));

	return 0;
}

SQInteger s_Graphics_Mesh_AddVertex (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQFloat					fX, fY, fZ;
	SQFloat					fU, fV;
	SQInteger				iRed, iGreen, iBlue;
	SQInteger				iAlpha;
	SQFloat					fNormalX, fNormalY, fNormalZ;

	fX = fY = fZ = 0;
	fU = fV = 0;
	iRed = iGreen = iRed = 0;
	iAlpha = 255;
	fNormalX = fNormalY = fNormalZ = 0;

	sq_getstring			(v, 2, &sMeshName);
	sq_getfloat				(v, 3, &fX);
	sq_getfloat				(v, 4, &fY);
	sq_getfloat				(v, 5, &fZ);
	sq_getfloat				(v, 6, &fU);
	sq_getfloat				(v, 7, &fV);
	sq_getinteger			(v, 8, &iRed);
	sq_getinteger			(v, 9, &iGreen);
	sq_getinteger			(v, 10, &iBlue);
	sq_getinteger			(v, 11, &iAlpha);
	sq_getfloat				(v, 12, &fNormalX);
	sq_getfloat				(v, 13, &fNormalY);
	sq_getfloat				(v, 14, &fNormalZ);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->AddVertex(fX, fY, fZ, fU, fV, Color(iRed, iGreen, iBlue, iAlpha), fNormalX, fNormalY, fNormalZ);

	return 0;
}

SQInteger s_Graphics_Mesh_AddTriangle (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex0, iVertexIndex1, iVertexIndex2;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex0);
	sq_getinteger			(v, 4, &iVertexIndex1);
	sq_getinteger			(v, 5, &iVertexIndex2);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->AddTriangle(iVertexIndex0, iVertexIndex1, iVertexIndex2);

	return 0;
}

SQInteger s_Graphics_Mesh_RemoveVertex (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->RemoveVertex(iVertexIndex);

	return 0;
}

SQInteger s_Graphics_Mesh_RemoveTriangle (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iTriangleIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iTriangleIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->RemoveTriangle(iTriangleIndex);

	return 0;
}

SQInteger s_Graphics_Mesh_Clear (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;

	sq_getstring			(v, 2, &sMeshName);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->ClearMesh();

	return 0;
}

SQInteger s_Graphics_Mesh_Build (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;

	sq_getstring			(v, 2, &sMeshName);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->BuildMesh();

	return 0;
}

SQInteger s_Graphics_Mesh_SetVertexPosition (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;
	SQFloat					fX, fY, fZ;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);
	sq_getfloat				(v, 4, &fX);
	sq_getfloat				(v, 5, &fY);
	sq_getfloat				(v, 6, &fZ);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->GetVertex(iVertexIndex)->position[0] = fX;
	pMesh->GetVertex(iVertexIndex)->position[1] = fY;
	pMesh->GetVertex(iVertexIndex)->position[2] = fZ;

	return 0;
}

SQInteger s_Graphics_Mesh_GetVertexPositionX (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushfloat			(v, pMesh->GetVertex(iVertexIndex)->position[0]);

	return 1;
}

SQInteger s_Graphics_Mesh_GetVertexPositionY (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushfloat			(v, pMesh->GetVertex(iVertexIndex)->position[1]);

	return 1;
}

SQInteger s_Graphics_Mesh_GetVertexPositionZ (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushfloat			(v, pMesh->GetVertex(iVertexIndex)->position[2]);

	return 1;
}

SQInteger s_Graphics_Mesh_SetVertexTexturePosition (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;
	SQFloat					fU, fV;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);
	sq_getfloat				(v, 4, &fU);
	sq_getfloat				(v, 5, &fV);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->GetVertex(iVertexIndex)->textureUV[0] = fU;
	pMesh->GetVertex(iVertexIndex)->textureUV[1] = fV;

	return 0;
}

SQInteger s_Graphics_Mesh_GetVertexTexturePositionU (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushfloat			(v, pMesh->GetVertex(iVertexIndex)->textureUV[0]);

	return 1;
}

SQInteger s_Graphics_Mesh_GetVertexTexturePositionV (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushfloat			(v, pMesh->GetVertex(iVertexIndex)->textureUV[1]);

	return 1;
}

SQInteger s_Graphics_Mesh_SetVertexColor (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;
	SQInteger				iRed, iGreen, iBlue;
	SQInteger				iAlpha;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);
	sq_getinteger			(v, 4, &iRed);
	sq_getinteger			(v, 5, &iGreen);
	sq_getinteger			(v, 6, &iBlue);
	sq_getinteger			(v, 7, &iAlpha);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->GetVertex(iVertexIndex)->color[0] = iRed;
	pMesh->GetVertex(iVertexIndex)->color[1] = iGreen;
	pMesh->GetVertex(iVertexIndex)->color[2] = iBlue;
	pMesh->GetVertex(iVertexIndex)->color[3] = iAlpha;

	return 0;
}

SQInteger s_Graphics_Mesh_GetVertexColorRed (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushinteger			(v, pMesh->GetVertex(iVertexIndex)->color[0]);

	return 1;
}

SQInteger s_Graphics_Mesh_GetVertexColorGreen (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushinteger			(v, pMesh->GetVertex(iVertexIndex)->color[1]);

	return 1;
}

SQInteger s_Graphics_Mesh_GetVertexColorBlue (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushinteger			(v, pMesh->GetVertex(iVertexIndex)->color[2]);

	return 1;
}

SQInteger s_Graphics_Mesh_GetVertexColorAlpha (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushinteger			(v, pMesh->GetVertex(iVertexIndex)->color[3]);

	return 1;
}

SQInteger s_Graphics_Mesh_SetVertexNormal (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;
	SQFloat					fNormalX, fNormalY, fNormalZ;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);
	sq_getfloat				(v, 4, &fNormalX);
	sq_getfloat				(v, 5, &fNormalY);
	sq_getfloat				(v, 6, &fNormalZ);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->GetVertex(iVertexIndex)->normal[0] = fNormalX;
	pMesh->GetVertex(iVertexIndex)->normal[1] = fNormalY;
	pMesh->GetVertex(iVertexIndex)->normal[2] = fNormalZ;

	return 0;
}

SQInteger s_Graphics_Mesh_GetVertexNormalX (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushfloat			(v, pMesh->GetVertex(iVertexIndex)->normal[0]);

	return 1;
}

SQInteger s_Graphics_Mesh_GetVertexNormalY (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushfloat			(v, pMesh->GetVertex(iVertexIndex)->normal[1]);

	return 1;
}

SQInteger s_Graphics_Mesh_GetVertexNormalZ (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQInteger				iVertexIndex;

	sq_getstring			(v, 2, &sMeshName);
	sq_getinteger			(v, 3, &iVertexIndex);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushfloat			(v, pMesh->GetVertex(iVertexIndex)->normal[2]);

	return 1;
}

SQInteger s_Graphics_Mesh_GetVertexCount (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;

	sq_getstring			(v, 2, &sMeshName);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushinteger			(v, pMesh->GetVertexCount());

	return 1;
}

SQInteger s_Graphics_Mesh_GetTriangleCount (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;

	sq_getstring			(v, 2, &sMeshName);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushinteger			(v, pMesh->GetTriangleCount());

	return 1;
}

SQInteger s_Graphics_Mesh_NeedsRebuilding (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;

	sq_getstring			(v, 2, &sMeshName);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	sq_pushbool				(v, pMesh->NeedsRebuilding());

	return 1;
}

SQInteger s_Graphics_Mesh_Translate	(HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQFloat					fX, fY, fZ;

	sq_getstring			(v, 2, &sMeshName);
	sq_getfloat				(v, 3, &fX);
	sq_getfloat				(v, 4, &fY);
	sq_getfloat				(v, 5, &fZ);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->Translate(fX, fY, fZ);

	return 0;
}

SQInteger s_Graphics_Mesh_Scale (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQFloat					fScaleX, fScaleY, fScaleZ;

	sq_getstring			(v, 2, &sMeshName);
	sq_getfloat				(v, 3, &fScaleX);
	sq_getfloat				(v, 4, &fScaleY);
	sq_getfloat				(v, 5, &fScaleZ);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->Scale(fScaleX, fScaleY, fScaleZ);

	return 0;
}

SQInteger s_Graphics_Mesh_Rotate (HSQUIRRELVM v)
{
	const SQChar			*sMeshName;
	SQFloat					fPitch, fYaw, fRoll;

	sq_getstring			(v, 2, &sMeshName);
	sq_getfloat				(v, 3, &fPitch);
	sq_getfloat				(v, 4, &fYaw);
	sq_getfloat				(v, 5, &fRoll);

	Mesh *pMesh = ResourceManager<Mesh>::GetResource(string(sMeshName));

	pMesh->Rotate(fPitch, fYaw, fRoll);

	return 0;
}